//deleteme
//GameState made by Kiko for testing purposes

#include "FakeGameState.h"
#include "Command.h"
#include <stdio.h>
#include <stdlib.h>

FakeGameState::FakeGameState()
{
	totalDeaths = 0;
	percentPopDied = 0;
	population = 0;
	totalGrain = 0;
	grainEatenByRats = 0;
	bushelsPerAcreHarvested = 0;
	acresOwned = 0;
	plagueProbability = 0;
	yearOfRule = 0;
	peopleStarved = 0;
	immigrants = 0;
	costPerAcre = 0;
	acresToPlant = 0;
	grainToFeedPeople = 0;
}

bool FakeGameState::Send(Command* Cmd)
{
	switch(Cmd->getCmdType())
	{
	case SSpawn:	return Spawn(Cmd);
	case SBarter:	return Barter(Cmd);
	case SFeed:		return Feed(Cmd);
	case SPlant:	return Plant(Cmd);
	case SQuit:		return End(Cmd);
	};
	Cmd->encode(Error, 0, "Invalid Command Type\n");
	return false;
}

bool FakeGameState::Spawn(Command* Cmd)
{
	totalDeaths = 0;
	percentPopDied = 0;
	population = 100;
	totalGrain = 2800;
	grainEatenByRats = 200;
	bushelsPerAcreHarvested = 3;
	acresOwned = 1000;
	plagueProbability = 1;

	yearOfRule = 1;
	peopleStarved = 0;
	immigrants = 5;
	costPerAcre = (rand() % 10) +17;

	sprintf_s(message,
		"TRY YOUR HAND AT GOVERNING ANCIENT SUMERIA SUCCESSFULLY\n"
		"FOR A 10-YR TERM OF OFFICE.\n\n"
		"HAMURABI:  I BEG TO REPORT TO YOU, IN YEAR %i,\n"	//year
		" %i PEOPLE STARVED,\n"								//starved
		" %i CAME TO THE CITY.\n"							//moved
		" POPULATION IS NOW %i.\n"							//pop
		" THE CITY NOW OWNS %i ACRES.\n"					//owned
		" YOU HARVESTED %i BUSHELS PER ACRE.\n"				//harvest
		" RATS ATE %i BUSHELS.\n"							//eaten
		" YOU NOW HAVE %i BUSHELS IN STORE.\n\n"			//total
		"LAND IS TRADING AT %i BUSHELS PER ACRE.\n"			//cost
		"HOW MANY ACRES DO YOU WISH TO BUY/SELL? (negative amount to sell) ",
		yearOfRule, peopleStarved, immigrants, population, acresOwned, bushelsPerAcreHarvested, grainEatenByRats, totalGrain, costPerAcre);
	
	Cmd->encode(RSpawn, 0, message);
	return true;
}

bool FakeGameState::Barter(Command* Cmd)
{
	int barter = Cmd->getValue();
	if(barter < 0)
		if(!Sell(Cmd))return false;
	if(!Buy(Cmd))return false;

	acresOwned += barter;
	totalGrain -= barter*costPerAcre;

	sprintf_s(message,
		"YOU HAVE %i BUSHELS OF GRAIN.\n"
		"HOW MANY BUSHELS DO YOU WISH TO FEED YOUR PEOPLE? ",
		totalGrain);

	Cmd->encode(RBarter, 0, message);
	return true;
}

bool FakeGameState::Buy(Command* Cmd)
{
	if( (Cmd->getValue()*costPerAcre) > totalGrain)
	{
		Cmd->encode(Error, 0, "YOU DON'T HAVE ENOUGH GRAIN TO AFFORD THAT PURCHASE\nHOW MANY ACRES DO YOU WISH TO BUY/SELL? (negative amount to sell) ");
		return false;
	}
	return true;
}

bool FakeGameState::Sell(Command* Cmd)
{
	if( ( Cmd->getValue()*(-1) ) > acresOwned)
	{
		Cmd->encode(Error, 0, "YOU CAN'T SELL MORE ACRES THAN YOU OWN\nHOW MANY ACRES DO YOU WISH TO BUY/SELL? (negative amount to sell) ");
		return false;
	}
	return true;
}

bool FakeGameState::Feed(Command* Cmd)
{
	grainToFeedPeople = Cmd->getValue();
	if(grainToFeedPeople < 0)
	{
		sprintf_s(message,
			"NEGATIVE NUMBERS ARE NOT ALLOWED\n"
			"YOU HAVE %i BUSHELS OF GRAIN.\n"
			"HOW MANY BUSHELS DO YOU WISH TO FEED YOUR PEOPLE? ",
			totalGrain);
		Cmd->encode(Error, 0, message);
		return false;
	}
	if(grainToFeedPeople > totalGrain)
	{
		sprintf_s(message,
			"YOU DO NOT HAVE THAT MUCH GRAIN\n"
			"YOU HAVE %i BUSHELS OF GRAIN.\n"
			"HOW MANY BUSHELS DO YOU WISH TO FEED YOUR PEOPLE? ",
			totalGrain);
		Cmd->encode(Error, 0, message);
		return false;
	}

	totalGrain -= grainToFeedPeople;

	sprintf_s(message,
		"YOU HAVE %i BUSHELS OF GRAIN.\n"
		"HOW MANY ACRES DO YOU WISH TO PLANT WITH SEED? ",
		totalGrain);
	
	Cmd->encode(RFeed, 0, message);
	return true;
}

bool FakeGameState::Plant(Command* Cmd)
{
	acresToPlant = Cmd->getValue();
	if(acresToPlant < 0)
	{		
		sprintf_s(message,
			"NEGATIVE NUMBERS ARE NOT ALLOWED\n"
			"YOU HAVE %i BUSHELS OF GRAIN.\n"
			"HOW MANY ACRES DO YOU WISH TO PLANT WITH SEED? ",
			totalGrain);
		Cmd->encode(Error, 0, message);
		return false;
	}
	if(acresToPlant > acresOwned)
	{
		sprintf_s(message,
			"YOU DO NOT OWN THAT MANY ACRES\n"
			"YOU HAVE %i BUSHELS OF GRAIN.\n"
			"HOW MANY ACRES DO YOU WISH TO PLANT WITH SEED? ",
			totalGrain);
		Cmd->encode(Error, 0, message);
		return false;
	}
	if( (acresToPlant/2) > totalGrain )
	{
		sprintf_s(message,
			"YOU DO NOT HAVE ENOUGH GRAIN\n"
			"YOU HAVE %i BUSHELS OF GRAIN.\n"
			"HOW MANY ACRES DO YOU WISH TO PLANT WITH SEED? ",
			totalGrain);
		Cmd->encode(Error, 0, message);
		return false;
	}
	if( acresToPlant > (10*population) )
	{
		sprintf_s(message,
			"BUT YOU HAVE ONLY %i PEOPLE TO TEND THE FIELDS.\n"
			"YOU HAVE %i BUSHELS OF GRAIN.\n"
			"HOW MANY ACRES DO YOU WISH TO PLANT WITH SEED? ",
			population, totalGrain);
		Cmd->encode(Error, 0, message);
		return false;
	}

	totalGrain -= int(acresToPlant/2);

	return Year(Cmd);
}

bool FakeGameState::Year(Command* Cmd)
{
	bushelsPerAcreHarvested=(rand() % 5) + 1;
	grainHarvested=acresToPlant*bushelsPerAcreHarvested;

	rValue = (rand() % 5) + 1;
	if (int(rValue/2) == rValue/2)
		grainEatenByRats = int(totalGrain / rValue);
	else
		grainEatenByRats = 0;

	totalGrain -= grainEatenByRats;
	totalGrain += grainHarvested;

	rValue = (rand() % 5) + 1;
	immigrants =int(((rValue*(20*acresOwned + totalGrain) / population )/ 100) + 1);

	peopleFed = int(grainToFeedPeople / 20);
	plagueProbability=(rand() % 100) - 15;
	if(population <= peopleFed)
		peopleStarved = 0;
	else
	{
		peopleStarved = population - peopleFed;
		if (peopleStarved > int ((45*population)/100))
		{
			sprintf_s(message, "\nYOU STARVED %i PEOPLE IN ONE YEAR!!!\n", peopleStarved);
			return Quit(Cmd);
		}
		else
		{
			percentPopDied=((yearOfRule - 1)* percentPopDied + (peopleStarved * 100 / population))/ yearOfRule;
			population= peopleFed;
			totalDeaths = totalDeaths + peopleStarved;
		}
	}

	yearOfRule++;

	if(plagueProbability > 0)
	{
		sprintf_s(message,
			"HAMURABI:  I BEG TO REPORT TO YOU, IN YEAR %i,\n"	//year
			" %i PEOPLE STARVED,\n"								//starved
			" %i CAME TO THE CITY.\n"							//moved
			" POPULATION IS NOW %i.\n"							//pop
			" THE CITY NOW OWNS %i ACRES.\n"					//owned
			" YOU HARVESTED %i BUSHELS PER ACRE.\n"				//harvest
			" RATS ATE %i BUSHELS.\n"							//eaten
			" YOU NOW HAVE %i BUSHELS IN STORE.\n\n"			//total
			"LAND IS TRADING AT %i BUSHELS PER ACRE.\n"			//cost
			"HOW MANY ACRES DO YOU WISH TO BUY/SELL? (negative amount to sell) ",
			yearOfRule, peopleStarved, immigrants, population, acresOwned, bushelsPerAcreHarvested, grainEatenByRats, totalGrain, costPerAcre);
	}
	else
	{
		population = int(population/2);
		sprintf_s(message,
			"HAMURABI:  I BEG TO REPORT TO YOU, IN YEAR %i,\n"	//year
			" %i PEOPLE STARVED,\n"								//starved
			" %i CAME TO THE CITY.\n"							//moved
			" A HORRIBLE PLAGUE STRUCK! HALF THE PEOPLE DIED."
			" POPULATION IS NOW %i.\n"							//pop
			" THE CITY NOW OWNS %i ACRES.\n"					//owned
			" YOU HARVESTED %i BUSHELS PER ACRE.\n"				//harvest
			" RATS ATE %i BUSHELS.\n"							//eaten
			" YOU NOW HAVE %i BUSHELS IN STORE.\n\n"			//total
			"LAND IS TRADING AT %i BUSHELS PER ACRE.\n"			//cost
			"HOW MANY ACRES DO YOU WISH TO BUY/SELL? (negative amount to sell) ",
			yearOfRule, peopleStarved, immigrants, population, acresOwned, bushelsPerAcreHarvested, grainEatenByRats, totalGrain, costPerAcre);
	}

	if(yearOfRule > 10)
	{
		sprintf_s(message,
			"\n\nHAMURABI:  I BEG TO REPORT TO YOU, IN YEAR %i,\n"	//year
			" %i PEOPLE STARVED,\n"									//starved
			" %i CAME TO THE CITY.\n"								//moved
			" POPULATION IS NOW %i.\n"								//pop
			" THE CITY NOW OWNS %i ACRES.\n"						//owned
			" YOU HARVESTED %i BUSHELS PER ACRE.\n"					//harvest
			" RATS ATE %i BUSHELS.\n"								//eaten
			" YOU NOW HAVE %i BUSHELS IN STORE.\n\n",				//total
			yearOfRule, peopleStarved, immigrants, population, acresOwned, bushelsPerAcreHarvested, grainEatenByRats, totalGrain);
		return Quit(Cmd);
	}
	Cmd->encode(RPlant, 0, message);
	return true;
}

bool FakeGameState::Quit(Command* Cmd)
{
	Cmd->encode(RQuit, 0, message);
	return true;
}

bool FakeGameState::End(Command* Cmd)
{
	int performanceStatus;

	if ((percentPopDied>33) || (acresOwnedPerPerson <7)) performanceStatus = 1;
	else if ((percentPopDied>10) || (acresOwnedPerPerson <9)) performanceStatus = 2;
	else if ((percentPopDied>3) || (acresOwnedPerPerson <10)) performanceStatus = 3;
	else performanceStatus = 4;

	acresOwnedPerPerson = acresOwned/population;

	switch(performanceStatus)
	{
	case 1:	EndOne();	break;
	case 2:	EndTwo();	break;
	case 3:	EndThree();	break;
	case 4:	EndFour();	break;
	};

	Cmd->encode(RQuit, 0, message);
	return true;
}

void FakeGameState::EndOne()
{
	sprintf_s(message,
		"IN YOUR 10-YEAR TERM OF OFFICE, %i PERCENT OF THE\n"	//percent
		"POPULATION STARVED PER YEAR ON AVERAGE, I.E., A TOTAL OF\n"
		"%i PEOPLE DIED!!"										//total
		"YOU STARTED WITH 10 ACRES PER PERSON AND ENDED WITH\n"
		"%i ACRES PER PERSON.\n"								//per person
		"DUE TO THIS EXTREME MISMANAGEMENT YOU HAVE NOT ONLY\n"
		"BEEN IMPEACHED AND THROWN OUT OF OFFICE BUT YOU HAVE\n"
		"ALSO BEEN DECLARED 'NATIONAL FINK' !!\n"
		"SO LONG FOR NOW.\n",
		percentPopDied, totalDeaths, acresOwnedPerPerson);
}

void FakeGameState::EndTwo()
{
	sprintf_s(message,
		"IN YOUR 10-YEAR TERM OF OFFICE, %i PERCENT OF THE\n"	//percent
		"POPULATION STARVED PER YEAR ON AVERAGE, I.E., A TOTAL OF\n"
		"%i PEOPLE DIED!!"										//total
		"YOU STARTED WITH 10 ACRES PER PERSON AND ENDED WITH\n"
		"%i ACRES PER PERSON.\n"								//per person
		"YOUR HEAVY-HANDED PERFORMANCE SMACKS OF NERO AND IVAN IV.\n"
		"THE PEOPLE (REMAINING) FIND YOU AN UNPLEASANT RULER, AND,\n"
		"FRANKLY, HATE YOUR GUTS!\n"
		"SO LONG FOR NOW.\n",
		percentPopDied, totalDeaths, acresOwnedPerPerson);
}

void FakeGameState::EndThree()
{
	sprintf_s(message,
		"IN YOUR 10-YEAR TERM OF OFFICE, %i PERCENT OF THE\n"	//percent
		"POPULATION STARVED PER YEAR ON AVERAGE, I.E., A TOTAL OF\n"
		"%i PEOPLE DIED!!"										//total
		"YOU STARTED WITH 10 ACRES PER PERSON AND ENDED WITH\n"
		"%i ACRES PER PERSON.\n"								//per person
		"YOUR PERFORMANCE COULD HAVE BEEN SOMEWHAT BETTER, BUT\n"
		"REALLY WASN'T TOO BAD AT ALL.\n"
		"%i PEOPLE WOULD\n"										//rand
		"DEARLY LIKE TO SEE YOU ASSASSINATED BUT WE ALL HAVE OUR\n"
		"TRIVIAL PROBLEMS.\n"
		"SO LONG FOR NOW.\n",
		percentPopDied, totalDeaths, acresOwnedPerPerson, int(float(population)*(float(rand() % 8)/10.0)));
}

void FakeGameState::EndFour()
{
	sprintf_s(message,
		"IN YOUR 10-YEAR TERM OF OFFICE, %i PERCENT OF THE\n"	//percent
		"POPULATION STARVED PER YEAR ON AVERAGE, I.E., A TOTAL OF\n"
		"%i PEOPLE DIED!!"										//total
		"YOU STARTED WITH 10 ACRES PER PERSON AND ENDED WITH\n"
		"%i ACRES PER PERSON.\n"								//per person
		"A FANTASTIC PERFORMANCE!!!  CHARLEMANGE, DISRAELI, AND\n"
		"JEFFERSON COMBINED COULD NOT HAVE DONE BETTER!\n"
		"SO LONG FOR NOW.\n",
		percentPopDied, totalDeaths, acresOwnedPerPerson);
}